package cn.edu.scau.cmi.ema.service;

import cn.edu.scau.cmi.ema.base.CmiPagination;
import cn.edu.scau.cmi.ema.domain.Crawlerdetectstatus;
import cn.edu.scau.cmi.ema.domain.Crawlerevent;
import cn.edu.scau.cmi.ema.service.base.CmiEmaService;
import cn.edu.scau.cmi.ema.util.CmiSqlUtil;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import java.util.*;
@Service("CrawlereventService")
@Transactional

public class CrawlereventServiceImpl extends CmiEmaService implements CrawlereventService {
	public CrawlereventServiceImpl() {
	}

	@Transactional
	public Crawlerevent saveCrawlerevent(Crawlerevent crawlerevent) {

		if (crawlerevent.getId() == null) {
			Crawlerdetectstatus crawlerdetectstatus = crawlerdetectstatusDAO
					.findCrawlerdetectstatusById(crawlerevent.getCrawlerdetectstatus().getId());

			Crawlerevent existingCrawlerevent = crawlereventDAO
					.findCrawlereventByPhysicalPrimaryKey(crawlerevent.getFilename(), crawlerevent.getRownumber());

			crawlerevent.setCrawlerdetectstatus(crawlerdetectstatus);

			if (isEquals(crawlerevent, existingCrawlerevent)) {
				return existingCrawlerevent;
			}

			crawlerevent = crawlereventDAO.store(crawlerevent);
			crawlereventDAO.flush();

		} else {
			Crawlerevent existingCrawlerevent = crawlereventDAO.findCrawlereventByPrimaryKey(crawlerevent.getId());

			crawlerevent = crawlereventDAO.store(crawlerevent);
			crawlereventDAO.flush();
		}

		return crawlerevent;
	}

	public void deleteCrawlerevent(Crawlerevent crawlerevent) {
		crawlereventDAO.remove(crawlerevent);
		crawlereventDAO.flush();
	}

	@Transactional
	public void deleteCrawlerevents(Set<Integer> deleteCrawlereventsId) {
		Query query = crawlereventDAO.createNamedQuery("deleteCrawlereventsById", -1, -1);
		query.setParameter(1, deleteCrawlereventsId);
		query.executeUpdate();
	}

	@Transactional
	public Set<Crawlerevent> loadCrawlerevents() {
		return crawlereventDAO.findAllCrawlerevents();

	}

	@Transactional
	public Set<Crawlerevent> loadReferenceCrawlerevents(Set<Crawlerevent> crawlerevents) {
		Iterator<Crawlerevent> crawlereventsIterator = crawlerevents.iterator();
		Set<Crawlerevent> referencedCrawlerevents = new HashSet<>();
		while (crawlereventsIterator.hasNext()) {
			Crawlerevent currentCrawlerevent = crawlereventsIterator.next();

		}
		return referencedCrawlerevents;
	}

	public Set<Crawlerevent> loadCrawlereventsByIdSet(Set<Integer> crawlereventIdSet) {

		Iterator<Integer> crawlereventIdIterator = crawlereventIdSet.iterator();
		Set<Crawlerevent> crawlereventSet = new HashSet<>();
		while (crawlereventIdIterator.hasNext()) {
			Integer id = crawlereventIdIterator.next();
			Crawlerevent currentCrawlerevent = crawlereventDAO.findCrawlereventById(id);
			crawlereventSet.add(currentCrawlerevent);
		}
		return crawlereventSet;
	}

	@Transactional
	public List<Crawlerevent> findAllCrawlerevents(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Crawlerevent>(crawlereventDAO.findAllCrawlerevents(startResult, maxRows));
	}

	@Transactional
	public Crawlerevent findCrawlereventByPrimaryKey(Integer id) {
		return crawlereventDAO.findCrawlereventByPrimaryKey(id);
	}

	@Transactional
	public Integer countCrawlerevents() {
		return ((Long) crawlereventDAO.createQuerySingleResult("select count(o) from Crawlerevent o").getSingleResult())
				.intValue();
	}

	@Transactional
	public Integer countCrawlerevents(CmiPagination page) {
		String sql = CmiSqlUtil.createCountHql(page, Crawlerevent.class);
		return ((Long) crawlereventDAO.createQuerySingleResult(sql).getSingleResult()).intValue();
	}

	/**
	 * search for name with ajax
	 *
	 */
	@Transactional
	public Integer countCrawlereventsByName(String queryName) {
		Query query = crawlereventDAO.createNamedQuery("countCrawlereventsByName", -1, -1);
		query.setParameter(1, queryName);
		return new Long((long) query.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countCrawlereventsByDetachedCriteria(CmiPagination page) {
		DetachedCriteria detachedCriteria = CmiSqlUtil.createDetachedCriteria(page, Crawlerevent.class);
		Session session = (Session) entityManager.getDelegate();
		detachedCriteria.setProjection(Projections.rowCount());
		return new Long((long) detachedCriteria.getExecutableCriteria(session).uniqueResult()).intValue();
	}

	public Map<String, ?> loadCrawlereventObjectReferencedSet(Crawlerevent crawlerevent) {
		HashMap<String, Object> objectReferencedSetMap = new HashMap<>();
		if (crawlerevent.getCrawlerdetectstatus() != null) {

			Set<Integer> crawlerdetectstatusIds = new HashSet<Integer>();
			crawlerdetectstatusIds.add(crawlerevent.getCrawlerdetectstatus().getId());
			objectReferencedSetMap.put("crawlerdetectstatusIds", crawlerdetectstatusIds);
		}

		return objectReferencedSetMap;
	}

	public Map<String, ?> loadCrawlereventClassReferencedSet(Crawlerevent crawlerevent) {
		HashMap<String, Object> classReferencedSetMap = new HashMap<>();
		classReferencedSetMap.put("crawlerdetectstatuss", crawlerdetectstatusDAO.findAllCrawlerdetectstatuss());

		return classReferencedSetMap;
	}

	public boolean isEquals(Crawlerevent crawlerevent, Object obj) {
		if (obj == crawlerevent)
			return true;
		if (!(obj instanceof Crawlerevent))
			return false;
		Crawlerevent comparedCrawlerevent = (Crawlerevent) obj;
		if (!CheckPropertyEqual(crawlerevent.getFilename(), comparedCrawlerevent.getFilename())) {
			return false;
		}
		if (!CheckPropertyEqual(crawlerevent.getRownumber(), comparedCrawlerevent.getRownumber())) {
			return false;
		}
		return true;
	}

	public static <T> boolean CheckPropertyEqual(T originProperty, T comparedProperty) {
		// 基本类型经过参数传递后会自动装箱
		String[] className = originProperty.getClass().getName().split("\\.");
		if (className[0].equals("java") && className[1].equals("math")) {
			return ((Comparable) originProperty).compareTo(comparedProperty) == 0 ? true : false;
		} else {
			return originProperty.equals(comparedProperty);
		}
	}
}

